
#include <stdio.h>
#include <stdlib.h>
#include "ManejadorBits.h"
#include "codigos.h"

/* *
 * 	COMPILAR CON:
 * 		gcc -std=c99 -Wall -pedantic -g -c "%f"
 * 
 * 	CONSTRUIR CON:
 *		gcc -std=c99 -Wall -pedantic -g -o "%e" "%f"
 * 
 *  EJECUTAR CON:
 * 		valgrind --track-origins=yes --leak-check=full ./%e
 * */

int cantidad_digitos (int num) {
	if (num < 0) num *= -1;
	int divisor = 1;
	int cociente = num / divisor;
	int digitos = 1;
	while (cociente >= 10) {
		digitos++;
		divisor *= 10;
		cociente = num / divisor;
	}
	return digitos;
}

void escritura (char* ruta) {
	FILE* fd = fopen (ruta, "wb");
	if (!fd) return;
	
	int repetidos[] = {   0   ,  1   , 3  ,   0   ,    3    ,     0    ,    1     };
	int distintos[] = {   4   ,  3   , 1  ,   4   ,    6    ,     7    ,    6     };
	char* cadenas[] = { "casa", "osa", "o", "hola", "ograma", "manzana", "ensaje" };
	int    offset[] = {  705  , 1014 , 50 , 78526 ,  55555  ,  3215678 ,  442200  };
	
	int* num = malloc (sizeof(int));
	if (!num) {
		fclose (fd);
		return;
	}
	
	/* FORMATO: repetidos distintos cadena offset */
	for ( int i = 0 ; i < 7 ; i++ ) {
		*num = repetidos[i];
		fwrite ( (const void*) num, sizeof (int), 1, fd );
		
		*num = distintos[i];
		fwrite ( (const void*) num, sizeof (int), 1, fd );
		
		fwrite ( cadenas[i], sizeof (char), distintos[i], fd );
		
		*num = offset[i];
		fwrite ( (const void*) num, sizeof (int), 1, fd );
	}
	fclose (fd);
	free (num);
}
void lectura_lexico (char* ruta) {
	
	ManejadorBits_t* manejador = ManejadorBits_crear (ruta, false);
	if (!manejador) return;
	
	for ( int i = 0 ; i < 15 ; i++ ) {
		// largo
		
		long repetidos = cod_gamma_leer(manejador);	
		printf ("\nEl repetidos es: %ld" , repetidos);
		long distintos = cod_gamma_leer(manejador);	
		printf ("\nEl distintos es: %ld" , distintos);
		char* cadena = ManejadorBits_leer_cadena (manejador , distintos );
		printf ("\nLa cadena es: %s", cadena);
		long offset = cod_delta_leer(manejador);	
		printf ("\nLa offset es: %ld\n", offset);
		
		free (cadena);
	}
	
	printf("\n\n");
	ManejadorBits_destruir (manejador);
	
}


void lectura_lexico_enteros (char* ruta) {
	FILE* fd = fopen (ruta, "rb");
	if (!fd) return;
	
	int* num = malloc (sizeof(int));
	if (!num) {
		fclose (fd);
		return;
	}
	/* FORMATO: repetidos distintos cadena offset */
	int i = 0;
	while ( !(feof (fd)) ) {
		*num = -1;
		
		// repetidos
		fread (num, sizeof(int), 1, fd);
		if ( (*num) == -1 ) break;
		printf ("Registro %d leido: (%d, ", i, *num);
		
		// distintos
		fread (num, sizeof(int), 1, fd);
		printf ("%d, ", *num);
		
		// cadena
		int largo = *num;
		char* cadena = malloc ( sizeof(char) * (largo+1) );
		fread (cadena, sizeof(char), largo, fd);
		cadena[largo] = '\0';
		printf ("%s, ", cadena);
		free (cadena);
		
		// offset
		fread (num, sizeof(int), 1, fd);
		printf ("%d)\n", *num);
		
		i++;
	}
	fclose (fd);
	free (num);
}


void lectura_datos (char* ruta) {
	
	ManejadorBits_t* manejador = ManejadorBits_crear (ruta, false);
	if (!manejador) return;
	
	for ( int i = 0 ; i < 50 ; i++ ) {
		// largo
		long largo = cod_delta_leer(manejador);	
		printf ("%ld-" , largo);		
	}
	
	printf("\n\n");
	ManejadorBits_destruir (manejador);
}

void lectura_datos_enteros (char* ruta) {
	FILE* fd = fopen (ruta, "rb");
	if (!fd) return;
	
	int* num = malloc (sizeof(int));
	if (!num) {
		fclose (fd);
		return;
	}
	/* FORMATO: frecuenciaD, docs, frecuenciaD1, posD1.... */ 
	int i = 0;
	while ( !(feof (fd)) ) {
		*num = -1;
		//printf ("Registro %d leido: (", i);
		// repetidos
		fread (num, sizeof(int), 1, fd);
		if ( (*num) == -1 ) break;
		printf ("%d, ", *num);
		
		i++;
	}
	printf ("\n\n");
	fclose (fd);
	free (num);
}

void lectura_datos_con_seek (char* ruta) {
	FILE* fd = fopen	 (ruta, "rb");
	if (!fd) return;
	
	int* num = malloc (sizeof(int));
	if (!num) {
		fclose (fd);
		return;
	}
	/* FORMATO: frecuenciaD, docs, frecuenciaD1, posD1.... */ 
	fseek (fd, 88, SEEK_SET);
	for ( int i = 0 ; i < 4 ; i++ ) {
		fread (num, sizeof(int), 1, fd);
		printf ("%d, ", *num);
	}
	
	fclose (fd);
	free (num);
}

void lectura_doc_int(char* ruta){
	FILE* fd = fopen(ruta, "rb");
	if (!fd) return;
	
	int* num = malloc (sizeof(int));
	if (!num) {
		fclose (fd);
		return;
	}
	/* FORMATO: repetidos distintos cadena offset */
	int i = 0;
	while ( !(feof (fd)) ) {
		*num = -1;
		// repetidos
		fread (num, sizeof(int), 1, fd);
		if ( (*num) == -1 ) break;
		printf ("%d",*num);
		
		// cadena
		int largo = *num;
		char* cadena = malloc ( sizeof(char) * (largo+1) );
		fread (cadena, sizeof(char), largo, fd);
		cadena[largo] = '\0';
		printf ("%s", cadena);
		free (cadena);
		i++;
	}
	printf("\n\n");
	fclose (fd);
	free (num);
}

void lectura_doc (char* ruta) {
	ManejadorBits_t* manejador = ManejadorBits_crear (ruta, false);
	if (!manejador) return;
	
	for ( int i = 0 ; i < 15 ; i++ ) {
		// largo
		long largo = cod_gamma_leer(manejador);	
		printf ("\nEl repetidos es: %ld\n" , largo);
		char* cadena = ManejadorBits_leer_cadena (manejador , largo);
		printf ("La cadena es: %s\n", cadena);
		free (cadena);
	}
	
	printf("\n\n");
	ManejadorBits_destruir (manejador);
}

void lectura_docs_con_seek (char* ruta) {
	ManejadorBits_t* manejador = ManejadorBits_crear (ruta, false);
	if (!manejador) return;
	
	ManejadorBits_seek (manejador, 0);
	long largo = cod_gamma_leer(manejador);	
	printf ("\nEl repetidos es: %ld\n" , largo);
	char* cadena = ManejadorBits_leer_cadena (manejador , largo);
	printf ("La cadena es: %s\n", cadena);
	free (cadena);
	
	ManejadorBits_seek (manejador, 1031);
	largo = cod_gamma_leer(manejador);	
	printf ("\nEl repetidos es: %ld\n" , largo);
	cadena = ManejadorBits_leer_cadena (manejador , largo);
	printf ("La cadena es: %s\n", cadena);
	free (cadena);
	
	ManejadorBits_seek (manejador, 504);
	largo = cod_gamma_leer(manejador);	
	printf ("\nEl repetidos es: %ld\n" , largo);
	cadena = ManejadorBits_leer_cadena (manejador , largo);
	printf ("La cadena es: %s\n", cadena);
	free (cadena);
	
}

int main () {
	//printf ("cantidad: %d\n", cantidad_digitos (-10));
	
	//escritura ("archivo.dat");
	//lectura_lexico ("y_lexico_gulliver.dat");
	//lectura_datos ("y_datos_gulliver.dat");
	
	//lectura_doc("documentos.dat");
	/*lectura_lexico ("a_lexico_nico.dat");
	lectura_datos ("a_datos_nico.dat");
	lectura_lexico ("a_lexico_nicoPrueba.dat");
	lectura_datos ("a_datos_nicoPrueba.dat");
	lectura_lexico ("a_lexico_prueba.dat");
	lectura_datos ("a_datos_prueba.dat");*/
	
	//lectura_lexico ("a_lexico_NOMBRE.dat");
	//lectura_datos ("a_datos_NOMBRE.dat");
	
	printf ("Lectura del archivo documentos: \n");
	lectura_doc("Indices/MAXI/documentos.dat");
	
	printf ("Lectura de un lexico: \n");
	lectura_lexico ("Indices/MAXI/v_lexico_MAXI.mnd");
	
	printf ("Lectura de un datos: \n");
	lectura_datos ("Indices/MAXI/v_datos_MAXI.mnd");
	
	//lectura_datos_con_seek ("8_datos_Archivo2.dat");
	lectura_docs_con_seek ("Indices/MAXI/documentos.dat");
	return 0;
}
